package com.ruoyi.law.controller;


import cn.felord.payment.wechat.v3.WechatApiProvider;
import cn.felord.payment.wechat.v3.WechatBatchTransferApi;
import cn.felord.payment.wechat.v3.WechatResponseEntity;
import cn.felord.payment.wechat.v3.model.batchtransfer.CreateBatchTransferParams;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageCondition;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.law.domain.dto.LawCashOutDTO;
import com.ruoyi.law.domain.entity.LawCashOut;
import com.ruoyi.law.domain.entity.LawTeam;
import com.ruoyi.law.enums.OutCashState;
import com.ruoyi.law.enums.OutCashWay;
import com.ruoyi.law.enums.UserRoleType;
import com.ruoyi.law.service.ILawCashOutService;
import com.ruoyi.law.service.ILawTeamService;
import com.ruoyi.law.utils.OrderUtil;
import com.ruoyi.law.utils.UserUtil;
import com.ruoyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 提现管理 前端控制器
 * </p>
 *
 * @author code
 * @since 2022-12-01
 */
@Slf4j
@Api(tags = "提现管理")
@RestController
@RequestMapping("/cashOut")
public class LawCashOutController extends BaseController {

    @Autowired
    private ILawCashOutService cashOutService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ILawTeamService teamService;
    @Autowired
    private WechatApiProvider wechatApiProvider;
    @Value("${wechat.pay.v3.miniApp.app-id}")
    private String appid;

    @ApiOperation("列表")
    @GetMapping("/list")
    public R<Page<LawCashOutDTO>> list(PageCondition<LawCashOut> pageCondition, Long userId, String role) {
        Page<LawCashOut> page = cashOutService.lambdaQuery()
                .eq(ObjectUtil.isNotNull(userId), LawCashOut::getUserId, userId)
                .eq(StrUtil.isNotBlank(role), LawCashOut::getRole, role)
                .page(pageCondition.toPage());
        List<LawCashOut> records = page.getRecords();
        List<LawCashOutDTO> dtoList = BeanUtil.copyToList(records, LawCashOutDTO.class);
        for (LawCashOutDTO dto : dtoList) {
            String userName = userService.getUserName(dto.getUserId());
            dto.setUserName(userName);
        }
        Page<LawCashOutDTO> dtoPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        dtoPage.setRecords(dtoList);
        return R.ok(dtoPage);
    }

    @ApiOperation("详情")
    @GetMapping("/info")
    public R<LawCashOut> info(Long id) {
        LawCashOut lawCashOut = cashOutService.getById(id);
        return R.ok(lawCashOut);
    }

    @ApiOperation("新增")
    @PostMapping("/save")
    public R<Object> save(@RequestBody LawCashOut lawCashOut) {
        Long userId = SecurityUtils.getUserId();
        SysUser user = userService.selectUserById(userId);
        Assert.notBlank(user.getRemark(), "请先实名！");

        BigDecimal money = lawCashOut.getMoney();
        BigDecimal amount = user.getAmount();
        if (money.compareTo(amount) > 0) {
            return R.fail("余额不足,无法提现");
        }

        // 提现用户是否是律师
        Integer count = teamService.lambdaQuery()
                .eq(LawTeam::getUserId, userId)
                .count();
        lawCashOut.setRole(count == 0 ? UserRoleType.ordinaryUser.getType() : UserRoleType.lawyer.getType());

        // 待处理
        lawCashOut.setState(OutCashState.toBeProcessed.getValue());
        lawCashOut.setUserId(userId);
        lawCashOut.setNum(OrderUtil.getOrderNum(lawCashOut.getUserId()));
        lawCashOut.setOutBatchNo(OrderUtil.getOrderNum(lawCashOut.getUserId()));
        cashOutService.save(lawCashOut);
        return R.ok();
    }

    @ApiOperation("审核")
    @PostMapping("/audit")
    public R<String> audit(@RequestBody LawCashOut lawCashOut) {
        String msg = "";
        if (OutCashState.agree.getValue().equals(lawCashOut.getState())) {
            // 扣除用户余额
            Long userId = lawCashOut.getUserId();
            BigDecimal money = lawCashOut.getMoney();
            SysUser user = UserUtil.getUser(userId);
            user.setAmount(user.getAmount().subtract(money));
            userService.updateUser(user);

            if (OutCashWay.online.getValue().equals(lawCashOut.getWay())) {
                // 同意线上提现 调用微信接口
                // 转为分
                int fen = money.multiply(new BigDecimal(100)).intValue();
                msg = withdrawal(fen, user, lawCashOut);
            }
        }
        cashOutService.updateById(lawCashOut);
        return R.ok(msg);
    }

    /**
     * 微信提现
     *
     * @param money      钱(分)
     * @param user       用户
     * @param lawCashOut 提现信息
     * @return {@link String}
     */
    private String withdrawal(int money, SysUser user, LawCashOut lawCashOut) {
        String msg;
        WechatBatchTransferApi miniApp = wechatApiProvider.batchTransferApi("miniApp");
        CreateBatchTransferParams transferParams = new CreateBatchTransferParams();

        transferParams.setAppid(appid);
        transferParams.setOutBatchNo(lawCashOut.getOutBatchNo());
        transferParams.setBatchName("微信提现");
        transferParams.setBatchRemark("微信提现");

        CreateBatchTransferParams.TransferDetailListItem transferDetailListItem =
                new CreateBatchTransferParams.TransferDetailListItem();
        transferDetailListItem.setOutDetailNo(lawCashOut.getNum());
        transferDetailListItem.setTransferAmount(money);
        transferDetailListItem.setTransferRemark("提现");
        transferDetailListItem.setOpenid(user.getOpenid());
        // remark存用户的真实姓名
        transferDetailListItem.setUserName(user.getRemark());

        transferParams.setTransferDetailList(Collections.singletonList(transferDetailListItem));
        transferParams.setTotalAmount(money);
        transferParams.setTotalNum(1);

        WechatResponseEntity<ObjectNode> responseEntity = miniApp.batchTransfer(transferParams);
        log.info("微信提现返回结果:{}", responseEntity);
        msg = responseEntity.getBody().toString();
        return msg;
    }

}
